#include "SDL/SDL.h"
#include <stdio.h>      /* printf, scanf, puts, NULL */
#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */
#include "engine.h"
#include <list>
#include "NeuralNet.h"
#include <math.h>


using namespace std;

const int WINDOW_WIDTH = 1000;
const int WINDOW_HEIGHT = 600;
const int ENTITY_NUMBER = 4;
const int FOOD_NUMBER = 100;
const char* WINDOW_TITLE = "Test Neural Net";

bool check_collision( SDL_Rect A, SDL_Rect B )
{
    //The sides of the rectangles
    int leftA, leftB;
    int rightA, rightB;
    int topA, topB;
    int bottomA, bottomB;

    //Calculate the sides of rect A
    leftA = A.x;
    rightA = A.x + A.w;
    topA = A.y;
    bottomA = A.y + A.h;

    //Calculate the sides of rect B
    leftB = B.x;
    rightB = B.x + B.w;
    topB = B.y;
    bottomB = B.y + B.h;
    //If any of the sides from A are outside of B
    if( bottomA <= topB )
    {
        return false;
    }

    if( topA >= bottomB )
    {
        return false;
    }

    if( rightA <= leftB )
    {
        return false;
    }

    if( leftA >= rightB )
    {
        return false;
    }

    //If none of the sides from A are outside B
    return true;
}

int main(int argc, char **argv)
{
	SDL_Init( SDL_INIT_VIDEO );
	srand ( time( NULL ) );

	SDL_Surface* screen = SDL_SetVideoMode( WINDOW_WIDTH, WINDOW_HEIGHT, 0, SDL_HWSURFACE | SDL_DOUBLEBUF );
	SDL_WM_SetCaption( WINDOW_TITLE, 0 );

	SDL_Surface* entity = SDL_LoadBMP("/home/dennj/Desktop/eclipse cpp/project/TestWorld/src/c.bmp");

	// Food sprite
	SDL_Rect foodArray[FOOD_NUMBER];
	for( int i = 0; i < FOOD_NUMBER; i++){
		foodArray[i] = { rand() % WINDOW_WIDTH, rand() % WINDOW_HEIGHT, 4, 4 };
	}

	//mine
	list<SDL_Rect> mine;
	for( int i = 0; i < FOOD_NUMBER; i++){
		mine.push_back( { rand() % WINDOW_WIDTH, rand() % WINDOW_HEIGHT, 4, 4 } );
	}

	Uint32 red = SDL_MapRGB(screen->format,255,0,0);
	Uint32 blue = SDL_MapRGB(screen->format,0,0,255);
	Uint32 green = SDL_MapRGB(screen->format,0,255,0);

	// Part of the screen we want to draw the sprite to
	SDL_Rect destination[ ENTITY_NUMBER ];
	NeuralNet Entity [ ENTITY_NUMBER ];
	int healt[ ENTITY_NUMBER ];
	int counter[ ENTITY_NUMBER ];// unit of food eaten
	for( int i = 0; i < ENTITY_NUMBER; i++ ){// create entity
		destination[i].x = rand() % WINDOW_WIDTH;
		destination[i].y = rand() % WINDOW_HEIGHT;
		destination[i].w = 65;
		destination[i].h = 44;
		healt[i] = 1000;
		counter[i] = 0;
	}

	SDL_Event event;
	bool gameRunning = true;

	while ( gameRunning )
	{
		if ( SDL_PollEvent( &event ) )
		{
			if ( event.type == SDL_QUIT )
			{
				gameRunning = false;
			}
		}

		//draw food
		for( int i = 0; i < FOOD_NUMBER; i++ ){
			SDL_FillRect( screen, &foodArray[i], green );
		}

		//draw mine
		list<SDL_Rect>::iterator p;
		for (p = mine.begin(); p != mine.end(); p++){
			SDL_FillRect( screen, &*p, blue );
		}

		for( int i = 0; i < ENTITY_NUMBER; i++ ){ // for every entity
			//move entity
			double speed = 2000 / ( healt[i] + 1000 );

			//find nearest food
			int nearest = 0;
			for( int j = 1; j < 100; j++ )
				if (  pow( foodArray[nearest].x - destination[i].x, 2 ) + pow( foodArray[nearest].y - destination[i].y, 2 ) > ( foodArray[j].x - destination[i].x, 2 ) + pow( foodArray[j].y - destination[i].y, 2 )  )
					nearest = j;

			double directionfood = atan( foodArray[nearest].y / ( foodArray[nearest].x + .0001 ) );
			double Tmp[] = {directionfood, 0, 0, 1};

			Entity[i].Think( Tmp );

			destination[i].x += Tmp[0]>.5?1:-1;//2*(foodArray[nearest].x - destination[i].x  )/sqrt( pow( foodArray[nearest].x - destination[i].x, 2 ) + pow( foodArray[nearest].y - destination[i].y, 2 ) ) ;;
			destination[i].y += Tmp[0]>.5?1:-1;;//*Tmp[1];//2*( foodArray[nearest].y - destination[i].y )/sqrt( pow( foodArray[nearest].x - destination[i].x, 2 ) + pow( foodArray[nearest].y - destination[i].y, 2 ) ) ;// 1 * cos( Tmp[0] );


			//check if out of bound
			if( destination[i].y >= WINDOW_HEIGHT - 28 )
				destination[i].y = WINDOW_HEIGHT - 28;
			if( destination[i].x >= WINDOW_WIDTH - 28 )
				destination[i].x = WINDOW_WIDTH - 28;

			// check collision
			for( int j = 0; j < 100; j++ ){
				if ( check_collision( foodArray[j], destination[i] ) ){
					healt[i]+=100;
					counter[i]++;
					foodArray[j] = { rand() % WINDOW_WIDTH, rand() % WINDOW_HEIGHT, 4, 4 };
				}
			}

			//mine move
			list<SDL_Rect>::iterator p;
			for (p = mine.begin(); p != mine.end(); p++){
				//	(*p).x+=speed;// mine speed
			}

			//check mine collision
			for (p = mine.begin(); p != mine.end(); p++){
				if( check_collision( *p, destination[i] ) ){
					//healt[i] -= 200;
					*p = { rand() % WINDOW_WIDTH, rand() % WINDOW_HEIGHT, 4, 4 };
				}
			}

			if( --healt[i] < 0 ){ // a ogni ciclo la fame aumenta
				destination[i].x = rand() % WINDOW_WIDTH; // create new entity
				destination[i].y = rand() % WINDOW_HEIGHT;
				destination[i].w = 65;
				destination[i].h = 44;
				healt[i] = 1000;
				counter[i] = 0;
			}

			//life bar
			SDL_Rect life = { destination[i].x, destination[i].y-8, healt[i]/30, 4 };
			SDL_FillRect( screen, &life, SDL_MapRGB(screen->format, 255-healt[i]/5, healt[i]/5, 0) );
			//SDL_SetAlpha(entity, SDL_SRCALPHA, 50 + healt[i]/5);
		//	entity = SDL_DisplayFormatAlpha( entity );
		//	SDL_SetColorKey(entity, SDL_SRCCOLORKEY, SDL_MapRGB(screen->format,255 - healt[i]/5,0,0));
			SDL_BlitSurface( entity, NULL, screen, &destination[i] );
		}

		SDL_Flip( screen );
		SDL_Delay( 10 );

		SDL_FillRect( screen, 0, SDL_MapRGB(screen->format,10,0,0) );// clear screen
	}

	SDL_FreeSurface( entity );
	SDL_Quit();
	return 0;
}



